package main

import "fmt"

/*
20_策略模式
概念：定义一系列的算法，把它们一个个封装起来，并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
*/

// PaymentContext 支付环境
type PaymentContext struct {
	Name, CardId string
	Money        int
}

// 支付策略
type PaymentStrategy interface {
	Pay(ctx *PaymentContext)
}

// 支付
type Payment struct {
	Context  *PaymentContext
	Strategy PaymentStrategy
}

func NewPayment(name, cardId string, money int, strategy PaymentStrategy) *Payment {
	return &Payment{
		Context: &PaymentContext{
			Name:   name,
			CardId: cardId,
			Money:  money,
		},
		Strategy: strategy,
	}
}

func (p *Payment) Pay() {
	p.Strategy.Pay(p.Context)
}

// 付款
type Cash struct {
}

func (c *Cash) Pay(ctx *PaymentContext) {
	fmt.Printf("支付%v元到%v\n", ctx.Money, ctx.Name)
}

// 银行
type Bank struct {
}

func (b *Bank) Pay(ctx *PaymentContext) {
	fmt.Printf("支付%v元到%v (银行账号为：%v)\n", ctx.Money, ctx.Name, ctx.CardId)
}

func main() {
	c := &Cash{}
	payment := NewPayment("张三", "10086", 666, c)
	payment.Pay()

	b := &Bank{}
	payment = NewPayment("张三", "10086", 666, b)
	payment.Pay()
}
